package com.kebima.twitter

import junit.framework._;
import Assert._;

object TwitterTest {
  def suite: Test = {
      val suite = new TestSuite(classOf[TwitterTest]);
      suite
  }
}

class TwitterTest {
  
  val unauth = TwitterSession()
  // this is the userid/password of the main user used to drive the program.
  // tests will update status, send messages, add/remove friends, etc, so make sure
  // you're willing to tolerate some noise on this account
  val twitterUser  = ""
  val twitterPassword = ""
  
  // the account to use to test the friends timeline calls.  Should have more than 100 friends
  // to adequately test paging
  val friendsUser = ""
  
  // the id of a given tweet.  Any (public) tweet will work
  val statusId = 0
  
  // the userid/name of somebody who has more than 20 favorited items
  val favoritesUser = ""

  // an account that is followed by the main account, and also follows the main account.
  // this is what we test direct messages with
  val friendsWithUser = ""
  
  // the screen name of a user the driver account is *not* friends with
  val notFriendsWithUser = ""
  
  // a user to block (and then unblock).  Note that this kills their follow, so make sure
  // it's not an account you really follow
  val blockedUser = ""
  
  val auth = TwitterSession(twitterUser,twitterPassword)
  
  // these don't run against the rate limit
  def testPublicTimeline() = {assert(unauth.getPublicTimeline().length > 0)}
  def testFriendsStringTimeline() = {assert(unauth.getFriendsTimeline(friendsUser).length > 0)}
  def testGetStatus() = {assert(unauth.getStatus(statusId).id != 0)}
  def testGetFavorites() = {assert(unauth.getFavorites(favoritesUser).length > 0)}
  def testGetFavoritesPage() = {
    val pg1 = unauth.getFavorites(favoritesUser)
    val pg2 = unauth.getFavorites(favoritesUser,2)
    assert(pg2.length > 0)
    assert(pg1.head.id != pg2.head.id)
  }
  def testGetFeatured() = {assert(unauth.getFeatured().length > 0)}
  def testGetFriends() = {assert(unauth.getFriends(friendsUser).length > 0)}
  def testGetFriendsPage() = {
    val pg1 = unauth.getFriends(friendsUser)
    val pg2 = unauth.getFriends(friendsUser,2)
    assert(pg2.length > 0)
    assert(pg1.head.id != pg2.head.id)
  }
    
  //// Test authenticated methods.  
  
  // note: this batch counts against your rate limit, so be careful
  if(false){
    def testUserDetails = {assert(auth.getUserDetail(friendsUser).screenName != null)}
    def testDirectMessages = {
      val directs = auth.getDirectMessages()
      assert(directs.length > 0)
      assert(directs.head.recipient != null)
      assert(directs.head.sender != null)
      assert(directs.head.text != null)
      // populate directs before checking
      //val directs2 = auth.getDirectMessages(2)
      //assert(directs2.length > 0)
      //assert(directs2.head.id != directs.head.id)
    }
  
    def testSentMessages = {
      val sent = auth.getSentMessages()
      assert(sent.length > 0)
      assert(sent.head.recipient != null)
      assert(sent.head.sender != null)
      assert(sent.head.text != null)
      // populate sent and check
      //val sent2 = auth.getSentMessages(2)
      //assert(sent2.length > 0)
      //assert(sent2.head.id != sent.head.id)
    }
  
    def testGetFriendshipExists() = {assert(auth.getFriendshipExists(friendsWithUser,twitterUser))}
    def testGetFriendshipDoesNotExist() = {assert(!auth.getFriendshipExists(notFriendsWithUser,twitterUser))}
    def testVerifyCredentials() = {assert(auth.verifyCredentials())}
    def testUnverifiedCredentials() = {assert(!TwitterSession(twitterUser,twitterPassword+"foo").verifyCredentials())}
    def testGetArchive() = {assert(auth.getArchive().length > 0)}
    def testGetFollowers() = {assert(auth.getFollowers().length > 0)} // with page?
    def testGetReplies() = {assert(auth.getReplies().length > 0)} // with page?
    null
  }
  
  // since these are posts they don't hit your rate limit
  def testBlockUser() = {
    val blocked = auth.blockUser("lotd")
    val unblocked = auth.unblockUser("lotd")
    assert(blocked.id == unblocked.id)
  }
  def testCreateFavorite() = {
    val favorite = auth.createFavorite(statusId)
    val unfavorite = auth.destroyFavorite(statusId)
    assert(favorite.id == unfavorite.id)
  }
  def testCreateFriendship() = {
    try{
      if(!auth.getFriendshipExists(twitterUser,friendsWithUser)){
        auth.createFriendship(friendsWithUser)
      }
      val unfriend = auth.destroyFriendship(friendsWithUser)
      val friend = auth.createFriendship(friendsWithUser)
      assert(unfriend.id == friend.id)
    } catch {
      case e:TwitterException => println("exception in test create friendship: " + e.twitterMessage); throw e
      case e => println("exception in test create friendship: " + e.getMessage); throw e
    } 
  }

  def testNewDirectMessage() = {
    try{
      val message = auth.newDirectMessage(friendsWithUser,"hi there")
      assert(message.id != 0)
      // need to figure out a way to send a direct message and destroy it
      //val destroyed = auth.destroyDirectMessage(message.id)
      //assert(destroyed.id == message.id)
    } catch {
      case e:TwitterException => println("exception in test direct message: " + e.twitterMessage); throw e
      case e => println("exception in test direct message: " + e.getMessage); throw e
    } 
  }
  
  def testUpdateStatus() = {
    val message = auth.updateStatus("test update")
    val destroyed = auth.destroyStatus(message.id)
    assert(destroyed.id == message.id)
  }
 
  def testFollowNotifications() = {
    try{
      val followed = auth.followNotifications(friendsWithUser)
      val unfollowed = auth.leaveNotifications(friendsWithUser)
      assert(followed.id == unfollowed.id)
    } catch {
      case e:TwitterException => println("exception in test follow notifications: " + e.twitterMessage); throw e
      case e => println("exception in test follow notifications: " + e.getMessage); throw e
    } 
  }
  def testUpdateDeliveryService() = {
    assert(auth.updateDeliveryService("im") != null)
  }
  def testUpdateLocation() = {
    assert(auth.updateLocation("Santa Clara") != null)
  }
}